* bound yet. The exception is the 'misdirect VIRQ', which is permanently
* bound to port 0.
*/
- if ( ((port = ed->virq_to_evtchn[virq]) !=
- (ed->eid * EVENT_CHANNELS_SPREAD)) ||
+ if ( ((port = ed->virq_to_evtchn[virq]) != 0) ||
(virq == VIRQ_MISDIRECT) ||
((port = get_free_port(ed)) < 0) )
goto out;
chn1 = d1->event_channel;
/* NB. Port 0 is special (VIRQ_MISDIRECT). Never let it be closed. */
- if ( (port1 <= 0) || (port1 >= d1->max_event_channel) ||
- ((port1 & (EVENT_CHANNELS_SPREAD - 1)) == 0) )
+ if ( (port1 <= 0) || (port1 >= d1->max_event_channel) )
{
rc = -EINVAL;
goto out;
}
-int init_exec_domain_event_channels(struct exec_domain *ed)
-{
- struct domain *d = ed->domain;
- int port, ret = -EINVAL, virq;
-
- spin_lock(&d->event_channel_lock);
- port = ed->eid * EVENT_CHANNELS_SPREAD;
- if ( ((port < d->max_event_channel &&
- d->event_channel[port].state != ECS_FREE)) ||
- (get_free_port(ed) != port) )
- goto out;
- d->event_channel[port].state = ECS_VIRQ;
- d->event_channel[port].u.virq = VIRQ_MISDIRECT;
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- ed->virq_to_evtchn[virq] = port;
- ret = 0;
- out:
- spin_unlock(&d->event_channel_lock);
- return ret;
-}
-
int init_event_channels(struct domain *d)
{
spin_lock_init(&d->event_channel_lock);
- return init_exec_domain_event_channels(d->exec_domain[0]);
+ /* Call get_free_port to initialize d->event_channel */
+ if ( get_free_port(d->exec_domain[0]) != 0 )
+ return -EINVAL;
+ d->event_channel[0].state = ECS_VIRQ;
+ d->event_channel[0].u.virq = VIRQ_MISDIRECT;
+ return 0;
}
*/
static inline void send_guest_virq(struct exec_domain *ed, int virq)
{
- evtchn_set_pending(ed, ed->virq_to_evtchn[virq]);
+ int port = ed->virq_to_evtchn[virq];
+
+ /* Always deliver misdirect virq's to exec domain 0. */
+ if ( unlikely(port == 0) )
+ ed = ed->domain->exec_domain[0];
+ evtchn_set_pending(ed, port);
}
/*